/**
 * @author raelzhu
 * @version $Revision: 1.62 $
 */
Opal.Component = function(id) {
	this.id = id;
	this.element = $(id);
};

Opal.DataBinders = {
	label: function(element, binding) {
		return Opal.DataBinders.syncLabel(element, binding);
	},
	
	a: function(element, binding) {
		return Opal.DataBinders.syncLabel(element, binding);
	},
	
	input: function(element, binding) {
		switch(element.type.toLowerCase()) {
			case 'text':
			case 'password':
				return Opal.DataBinders.syncText(element, binding);
			case 'checkbox':
			case 'radio':
				return Opal.DataBinders.syncCheckboxOrRadio(element, binding);
		}
	},
	
	textarea: function(element, binding) {
		return Opal.DataBinders.syncText(element, binding);
	},
	
	select: function(element, binding) {
		var value = eval('context.' + binding);
		value = (value != undefined && value != null) ? value : '';
		for (var i = 0; i < element.options.length; i++) {
			var opt = element.options[i];
			if (opt.value == value) {
				element.selectedIndex = i;
				break;
			}
		}
	},
	
	syncText: function(element, binding) {
		var value = eval('context.' + binding);
		value = (value != undefined && value != null) ? value : '';
		element.value = value;
	},
	
	syncCheckboxOrRadio: function(element, binding) {
		var value = eval('context.' + binding);
		if (element.value == value) {
			element.checked = true;
		} else {
			element.checked = false;
		}
	},
	
	syncLabel: function(element, binding) {
		var value = eval('context.' + binding);
		value = (value != undefined && value != null) ? value : '';
		element.innerHTML = value;
	}
};

Opal.Core.HTMLComponent = {
	setBinding : function(expression) {
		this.binding = expression;
	},
	
	syncData: function() {
		var method = this.element.tagName.toLowerCase();
		return Opal.DataBinders[method](this.element, this.binding.value);
	},
	
	addEventListener: function(type, handler) {
		Event.observe(this.element, type, handler.bindAsEventListener(this));
	},
	
	setCommand: function(command) { this.element.setAttribute('command', command); },
	
	isLocked: function() { return this.element.readOnly; },
	lock: function() { this.element.readOnly = true; },
	unlock: function() { this.element.readOnly = false; },
	isDisabled: function() { return this.element.disabled; },
	disable: function() { this.element.disabled = true; },
	enable: function() { this.element.disabled = false; },
	isChecked: function() { return this.element.checked; },
	check: function() { this.element.checked = true; },
	uncheck: function() { this.element.checked = false; },
	isVisible: function() { return this.element.style.display != 'none'; },
	hide: function() { this.element.style.display = 'none'; },
	show: function() { this.element.style.display = ''; }
};

/***********************************************************/
Opal.Core.Label = function opal_core_label(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
};
Opal.Core.Label.prototype = Opal.Core.HTMLComponent;

Opal.Core.Anchor = function opal_core_anchor(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
};
Opal.Core.Anchor.prototype = Opal.Core.HTMLComponent;

Opal.Core.Button = function opal_core_button(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
};
Opal.Core.Button.prototype = Opal.Core.HTMLComponent;

Opal.Core.Checkbox = function opal_core_checkbox(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.element.onclick = function() {
		Opal.Util._setCursor(this.element);
		if (this.element.checked) {
			$populate_context(this.binding.value, this.element.value);
		} else {
			var value = eval('context.' + this.binding.uncheckedValue);
			value = (value != undefined && value != null) ? value : '';
			$populate_context(this.binding.value, value);
		}
	}.bind(this);
};
Opal.Core.Checkbox.prototype = Opal.Core.HTMLComponent;

Opal.Core.Radio = function opal_core_radio(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.element.onclick = function() {
		Opal.Util._setCursor(this.element);
		if (this.element.checked) {
			$populate_context(this.binding.value, this.element.value);
		}
	}.bind(this);
};
Opal.Core.Radio.prototype = Opal.Core.HTMLComponent;

Opal.Core.Editor = function opal_core_editor(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.element.onchange = function() {
		Opal.Util._setCursor(this.element);
		$populate_context(this.binding.value, this.element.value);
	}.bind(this);
};
Opal.Core.Editor.prototype = Opal.Core.HTMLComponent;

Opal.Core.Password = function opal_core_password(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.element.onchange = function() {
		Opal.Util._setCursor(this.element);
		$populate_context(this.binding.value, this.element.value);
	}.bind(this);
};
Opal.Core.Password.prototype = Opal.Core.HTMLComponent;

Opal.Core.Select = function opal_core_select(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.syncData = function() {
		var value = eval('context.' + this.binding.value);
		value = (value != undefined && value != null) ? value : '';
		for (var i = 0; i < this.element.options.length; i++) {
			var opt = this.element.options[i];
			if (opt.value == value) {
				this.element.selectedIndex = i;
				break;
			}
		}
	};
	
	this.element.onchange = function() {
		Opal.Util._setCursor(this.element);
		$populate_context(this.binding.value, this.element.value);
	}.bind(this);
	
	this.getSelectedIndex = function() {
		return this.element.selectedIndex;
	};
	
	this.getSelectedData = function() {
		var optionDatas = eval('context.' + this.binding.options) || [];
		return optionDatas[this.getSelectedIndex()];
	};
};
Opal.Core.Select.prototype = Opal.Core.HTMLComponent;

Opal.Core.RadioGroup = function opal_core_radio_group(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.syncData = function() {
		var value = eval('context.' + this.binding.value);
		value = (value != undefined && value != null) ? value : '';
		var obj = this;
		$A(this.element.getElementsByTagName('input')).each(function(it, index) {
			if (it.value == value) {
				obj.doCheck(index);
			}
		});
		
	};
	
	this.disable = function () {
		$A(this.element.getElementsByTagName('input')).each(function(it, index) {
			it.disabled = true;
		});
		this.element.disabled = true;
	};
	
	this.enable = function () {
		$A(this.element.getElementsByTagName('input')).each(function(it, index) {
			it.disabled = false;
		});
		this.element.disabled = false;
	};
	
	this.lock = this.disable;
	
	this.unlock = this.enable;
	
	this.isLocked = this.isDisabled;
	
	var obj = this;
	var n = this.element.getElementsByTagName('li').length;
	if (n > 0) {
		n.times(function(index) {
			Event.observe($(obj.id + '_option' + index), 'click', function(){obj.doCheck(index)});
			Event.observe($(obj.id + '_option' + index), 'mouseover', function(){obj.doHilite(index)});
			Event.observe($(obj.id + '_option' + index), 'mouseout', function(){obj.doRestore(index)});
		});
	}
	
	this.doCheck = function(index) {
		Opal.Util._setCursor(this.element);
		$(this.id + '_selector' + index).checked = true;
		$populate_context(this.binding.value, $(this.id + '_selector' + index).value);
		if (typeof this.selectedIndex == 'undefined') this.selectedIndex = -1;
		if (this.selectedIndex != index) {
			(this._changeHandlers || []).each(function(it){it()});
			this.selectedIndex = index;
		}
	}
	
	this.doHilite = function(index) {
		$(this.id + '_option' + index).style.fontWeight = 'bold';
	}
	
	this.doRestore = function(index) {
		$(this.id + '_option' + index).style.fontWeight = 'normal';
	}
	
	this.addEventListener = function(type, handler) {
		this['_' + type + 'Handlers'] = this['_' + type + 'Handlers'] || [];
		this['_' + type + 'Handlers'].push(handler);
	}
}
Opal.Core.RadioGroup.prototype = Opal.Core.HTMLComponent;

Opal.Core.Grid = function opal_core_grid(o) {
	Object.extend(this, o);
	this.element = $(this.id);
	$O.registerComponent(this.id, this);
	
	this.getCurrentRowIndex = function(event) {
		event = (event) ? event : window.event;
		var src = (event.target) ? event.target : event.srcElement;
		var currentRow = Opal.Util.getParentNodeByTagName(src, 'tr');
		var index = parseInt(currentRow.getAttribute('rowIdx'));
		$populate_context(this.binding.item, eval('context.' + this.binding.items)[index]);
		return index;
	}
};
Opal.Core.Grid.prototype = Opal.Core.HTMLComponent;
/***********************************************************/
Opal.Core.TextArea = function opal_core_textArea(id) {
	Opal.Component.apply(this, arguments);
	
	var obj = this;
	this._changeHandlers = [];
	this.element.onchange = function(event) {
		Opal.Util._setCursor(obj.element);
		// handle whitespace characters
		$populate_context(obj.binding, obj.element.value.replace(/\n/g, '\\n').replace(/\r/g, '\\r'));
		
		// event handlers
		for (var i = 0; i < obj._changeHandlers.length; i++) {
			obj._changeHandlers[i].call(obj, event);
		}
	};
};
Opal.Core.TextArea.prototype = Opal.Core.HTMLComponent;

Opal.Core.Hidden = function opal_core_hidden(id) {
	Opal.Component.apply(this, arguments);
};
Opal.Core.Hidden.prototype = Opal.Core.HTMLComponent;

Opal.Core.EIPGrid = function opal_core_eipgrid(id) {
	this.id = id;
	this.element = $(id);
	
	this.addEventListener = function(type, handler) {
		if (!this['_' + type + 'Handlers']) {
			this['_' + type + 'Handlers'] = [];
		}
		this['_' + type + 'Handlers'].push(handler);
	}
	
	this.toggleEdit = function(index) {
		this.doUpdate(this.activeRowIndex);
		this.makeEditable(index);
		// beforeEdit event
		if (this._beforeEditHandlers) {
			this._beforeEditHandlers.each(function(it) {
				it();
			});
		}
	}
}
Opal.Core.EIPGrid.prototype = Opal.Core.HTMLComponent;

/****************************************************************/
//Refactoring at 3/9/2007
Opal.Form = function(o) {
	this._fields = {};
	this._asyncParams = {};
	this.form = document.createElement('form');
	var formRef;
	
	var populateFormRef = function(formRef) {
		if (formRef) {
			this.setMethod(formRef.method);
			this.setAction(formRef.action);
			var obj = this;
			Form.getElements(formRef).each(function(el) {
				if (el.name == 'actionname') return;
				obj.addSimple(el.name, Form.Element.getValue(el));
			});
		}
	}.bind(this);
	
	if (typeof o =='string') {
		populateFormRef(document[o]);
	} else {
		if (typeof o.name != 'undefined')
			populateFormRef(document[o.name]);
		if (typeof o.action != 'undefined')
			this.setAction(o.action);
		if (typeof o.method != 'undefined')
		  this.setMethod(o.method);
		if (typeof o.pageName != 'undefined')
			this.setPageName(o.pageName);
		if (typeof o.actionName != 'undefined')
			this.setActionName(o.actionName);
		if (typeof o.target != 'undefined') 
			this.setTarget(o.target);
		if (typeof o.validators != 'undefined')
			this.setValidators.apply(this, o.validators);
		if (typeof o.emptyToNull != 'undefined')
			this.emptyToNull = o.emptyToNull;
		if (typeof o.autoErrorProcess != 'undefined')
		  this.autoErrorProcess = o.autoErrorProcess;
	}
}

Opal.Form.prototype = {
	_syncSubmit: function() {
		this.form.style.display = 'none';
		document.body.appendChild(this.form);
		if (this.form.target == undefined || this.form.target == '' || this.form.target == '_self' || this.form.target == '_parent') {
	  		var overLay = document.createElement('div');
	  		overLay.className = 'overlay';
	  		document.body.appendChild(overLay);
		}
		this.form.submit();
  	},
  	_asyncSubmit: function() {
    	this.addSimple('isAsyncRequest', true);
    	
    	var asyncParams = [];
    	$A(this.form.elements).each(function(el) {
				var tmpStr = encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
				asyncParams.push(tmpStr);
			});
			
		var getTargetWindow = function(target) {
			var targetWindow;
			var targetStr = '_self';
	        if (target) {
	          targetStr = target;
	        }
	        
	        if (targetStr == '_self') {
	        	targetWindow = window;
	        } else if (targetStr == '_top') {
	        	targetWindow = top;
	        } else if (targetStr == '_parent') {
	        	targetWindow = parent;
	        } else {
	        	var parentWindow = parent;
	        	while (parentWindow != null && targetWindow == null) {
	        		targetWindow = parentWindow.frames[targetStr];
	        		parentWindow = parentWindow.parent;
	        	}
			}
        
	        if (targetWindow == null) {
	          targetWindow = window;
	        }
        
        	return targetWindow;
      	};
    	
    	var targetStr = this.form.target;
    	var targetWindow = getTargetWindow(targetStr);
		var ajaxRequest = new Opal.Request({
			url: this.form.action,
			method: this.form.method,
			params: asyncParams,
			onComplete: function(datas) {
				if (datas.errorMessage) {
					var messageTable = '<TABLE height=271 cellSpacing=0 cellPadding=7 width=434 border=0><TR><TD vAlign=top background="' + contextPath + '/images/' + languagecode + '/Error_bg.gif">';
					messageTable += '<TABLE height="100%" cellSpacing=0 cellPadding=0 width="100%" border=0><TR><TD vAlign=top><P>&nbsp;</P>' + '<TABLE cellSpacing=0 cellPadding=0 width="95%" align=center border=0><TR><TD width=35>';
					messageTable += '<img src="' + contextPath + '/images/' + languagecode + '/Error.gif" /></TD><TD vAlign=top width="400" class=error_title style="padding-top:30px;">' + labelname.L_ErrorMsg + '</TD></TR>'; 
					messageTable += datas.errorMessage;
					messageTable += '</TABLE><P>&nbsp;</P></TD></TR>';
					messageTable += '<tr><td class=td_center height=1><button class="button1" style="width:60px" id="lbAction">' + labelname.L_Back + '</button></td></tr></TABLE></TD></TR></TABLE>';
					
					var box = new messagebox(messageTable);
					$('lbAction').focus();
				} else {
					if (targetStr == '_blank') {
						Opal.Util.popupWindow({
							url: datas.url
						});
					} else {
						Opal.Util.redirectTo({
							url: datas.url,
							target: targetWindow
						});
					}
				}
			}
		});
	      
		ajaxRequest.submit();
  },
	submit: function() {
		// TODO: validation
		var errorMessage = '';
		(this._validators || []).each(function(it) {
			errorMessage += it.validate().join('\n');
		});
		if (errorMessage != '') {
			Opal.Util.showMessage(errorMessage);
			return;
		}
		
		if (arguments.length > 0) {
			var tmp = {};
			$A(Form.serialize(this.form).split('&').sort()).each(function(it, index) {
				tmp[index] = it;
			});
      		Opal.Log.debug('form data:', tmp);
			return;
		}
		
		if (this.emptyToNull == true) {
			$A(this.form.elements).each(function(el) {
				if (el.value.toString().replace(/^\s*/, '') == '') {
					el.value = ' ';
				}
			});
		}
		
		if (this.autoErrorProcess) {
      		this._asyncSubmit();
    	} else {
    	  this._syncSubmit();
    	}
    
	},
	setAutoErrorProcess: function(isAutoProcess) {
    this.autoErrorProcess = isAutoProcess;
  },
	setValidators: function() {
		this._validators = [];
		var obj = this;
		$A(arguments).each(function(it) {
			obj._validators.push(Opal.Validator.Group.getGroup(it));
		});
	},
	setMethod: function(method) {
		this.form.method = method;
	},
	setAction: function(action) {
		this.form.action = action;
	},
	setPageName: function(pageName) {
		if (this.form.pagename) {
			this.form.pagename.value = pageName;
		} else {
			this.addSimple('pagename', pageName);
		}
	},
	setActionName: function(actionName) {
		if (this.form.actionname) {
			this.form.actionname.value = actionName;
		} else {
			this.addSimple('actionname', actionName);
		}
	},
	setTarget: function(targetName) {
		this.form.target = targetName;
	},
	addSimple: function(name, value) {
		var field;
		if (this._fields[name]) {
			field = this._fields[name];
		} else {
			field = document.createElement('input');
			field.type = 'hidden';
			field.name = name;
			this.form.appendChild(field);
		}
		field.value = (typeof value != 'undefined' && value != null) ? value.toString() : '';
		this._fields[name] = field;
	},
	addArray: function(name, arr) {
		var obj = this;
		$A(arr).each(function(it) {
			var field = document.createElement('input');
			field.type = 'hidden';
			field.name = name;
			field.value = it;
			obj.form.appendChild(field);
		});
	},
	addHashMap: function(name, map) {
		var obj = this;
		$H(map).each(function(it) {
			obj.addSimple(it.key, it.value);
		});
	},
	addVector: function(name, vector) {
		var obj = this;
		var numberOfRows = 0;
		$A(vector).each(function(map, index) {
			$H(map).each(function(it) {
				obj.addSimple(it.key + index, it.value);
			});
			numberOfRows++;
		});
		obj.addSimple('numrows', numberOfRows);
	},
	addBean: function(name, bean) {
		var obj = this;
		$H(bean).each(function(it) {
			obj.addSimple(name + '.' + it.key, it.value);
		});
	},
	addList: function(name, list) {
		var obj = this;
		$A(list).each(function(bean, index) {
			obj.addBean(name + '[' + index + ']', bean);
		});
	}
}
